﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Elderos.Highlight.Search;
using Elderos.Ontology;
using Elderos.Utils;

namespace Elderos.Highlight
{
    public class Highlighter : IHighlighter
    {
        #region Constructors
        public Highlighter(IEnumerable<ISearchStrategy> searchStrategies, ISearchResultAdapter searchResultAdapter,
            IRanker ranker, IAmbiguityResolver ambiguityResolver, IOntologyData ontology)
        {

            SearchStrategies = searchStrategies.ToArray();

            foreach (var searchStrategy in SearchStrategies)
            {
                if (!searchStrategy.IsInitialized)
                    searchStrategy.Initialize();
            }

            SearchResultAdapter = searchResultAdapter;

            Ontology = ontology;

            Ranker = ranker;
            AmbiguityResolver = new PooledAmbiguityResolver(ambiguityResolver.Clone);
        }
        #endregion

        #region Properties
        private ISearchStrategy[] SearchStrategies { get; set; }

        public ISearchResultAdapter SearchResultAdapter { get; private set; }

        public IRanker Ranker { get; private set; }

        public IAmbiguityResolver AmbiguityResolver { get; private set; }

        public IOntologyData Ontology { get; private set; }

        #endregion

        public List<Position> Search(string text)
        {
            Token[] tokens = Tokenizer.GetTokens(text);
            return Search(text, tokens);
        }

        private List<Position> Search(string text, Token[] tokens)
        {
            var preparedText = new PreparedText(text, tokens);
            var positions = SearchStrategies.SelectMany(x => x.Search(preparedText)).ToList();

            SearchResultAdapter.SetTokenInfo(positions, tokens);

            var clean = SearchResultAdapter.ProcessPositions(text, positions);

            return clean;
        }

        public HighlightResult Highlight(string text)
        {
            Token[] tokens = Tokenizer.GetTokens(text);
            var positions = Search(text, tokens);

            var result = new HighlightResult(positions) { Text = text, Tokens = tokens };

            Ranker.Rank(result);

            AmbiguityResolver.Process(result.Positions);

            return result;
        }

        public ArticleHighlight ProcessArticle(string text)
        {
            HighlightResult result = Highlight(text);
            return new ArticleHighlight(result.Positions);
        }
    }
}
